package gui;

import java.sql.SQLException;

import gui.threads.LoginThread;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import DBside.JDBCConnection;
import DBside.Tools;
import LogicSide.ManageUsers;
import LogicSide.Session;

public class Login {
	private final static int loginTextBoxWidth = 400; // width in px
	
	private static Display display;
	private static Session session;
	private static Shell shell;
	private static String username;
	private static String password;
	public static boolean done;

	public static void main(String[] args) {
		display = new Display();
		shell = createLogin();

		shell.open();
		shell.pack();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}

	public static Shell createLogin() {
		shell = new Shell(display);
		shell.setText("Music+ Login");

		RowLayout shellLayout = new RowLayout(SWT.VERTICAL);
		shellLayout.spacing = 50; // spacing between widgets in the shell
		shellLayout.fill = true;
		shell.setLayout(shellLayout);

		// Add background picture to login
		Image loginBackgroundImage = new Image(display, "background.jpg");
		shell.setBackgroundImage(loginBackgroundImage);
		shell.setBackgroundMode(SWT.INHERIT_FORCE);

		// Add logo picture to the login
		Image musicLogo = new Image(display, "music.png");
		Label musicLogoLabel = new Label(shell, SWT.LEFT);
		musicLogoLabel.setImage(musicLogo);

		// Add login panel Compostie
		Composite loginComposite = new Composite(shell, SWT.BORDER);
		//loginComposite.setLocation(0, 400);
		loginComposite.setLayout(new GridLayout(2, false)); // two widgets per
															// row, same size

		// Add login composite widgets: label, texts and a button.

		Label usernameLabel = new Label(loginComposite, SWT.CENTER);
		usernameLabel.setText("username:"); // set label text
		usernameLabel.setForeground(Display.getCurrent().getSystemColor(
				SWT.COLOR_WHITE)); // set label's text color
		final Text usernameText = new Text(loginComposite, SWT.SINGLE
				| SWT.BORDER);
		usernameText.setBackground(Display.getCurrent().getSystemColor(
				SWT.COLOR_GRAY)); // set textBox background color
		usernameText.setSize(loginTextBoxWidth, usernameText.getSize().y); // change
																			// text
																			// box
																			// width.
																			// keep
																			// height.
		usernameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));

		Label passwordLabel = new Label(loginComposite, SWT.NONE);
		passwordLabel.setText("password:");
		passwordLabel.setForeground(Display.getCurrent().getSystemColor(
				SWT.COLOR_WHITE)); // set label's text color
		final Text passwordText = new Text(loginComposite, SWT.SINGLE
				| SWT.PASSWORD | SWT.BORDER);
		passwordText.setSize(loginTextBoxWidth, passwordText.getSize().y); // change
																			// text
																			// box
																			// width.
																			// keep
																			// height
		passwordText.setBackground(Display.getCurrent().getSystemColor(
				SWT.COLOR_GRAY)); // set textBox background color
		passwordText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
				1, 1));

		Button loginButton = new Button(loginComposite, SWT.PUSH | SWT.FLAT);
		loginButton.setText("Proceed to your account");
		GridData data = new GridData();
		data.horizontalSpan = 2; // span 2 columns
		data.horizontalAlignment = SWT.FILL;
		loginButton.setLayoutData(data);

		loginButton.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent arg0) {
				final LoginThread loginThread = new LoginThread(usernameText.getText(), passwordText.getText(), session , shell, display);
				shell.setCursor(new Cursor(display, SWT.CURSOR_WAIT));
				loginThread.start();
			}
		});

		Button registerButton = new Button(loginComposite, SWT.PUSH | SWT.FLAT);
		registerButton.setText("Register");
		registerButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				true, 2, 1));

		registerButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				// DEBUG
				System.out.println("registerButton pressed");
				System.out.println(usernameText.getText());
				System.out.println(passwordText.getText());
				//
				Utils.loadingCursor(display, shell);

				// Validate text fields - true iff text fields are OK
				if (vaildateRegistrationTextFields(usernameText.getText(),
						passwordText.getText(), shell)) {
					username = usernameText.getText();
					password = passwordText.getText();
					Thread thread = new Thread(new Runnable() {
						
						@Override
						public void run() {
							
							try {
								// try to register new user
								JDBCConnection con = new JDBCConnection();
								con.openConnection(Tools.getHomeURL(),
										Tools.getUserName(), Tools.getPassword());
								final Session session = new Session(con, 0);
								final int user_id = ManageUsers.addUser(
										username,
										password, session);
								
								display.asyncExec(new Runnable() {
									@Override
									public void run() {
										Utils.regularCursor(display, shell);
										// user registered successfully
										if (user_id != -1) {
											session.setUser_id(user_id);
											shell.dispose();
											Shell mainShell = Main.createMain(display,
													session);
											mainShell.open();
											mainShell.pack();
											
											while (!mainShell.isDisposed()) {
												if (!display.readAndDispatch()) {
													display.sleep();
												}
											}
											display.dispose();
											session.getCon().closeConnection();
											
										} 
										else {
											Utils.popUpBox("Registration failed", "Username already exists.", shell);
										}
									}
								});
							} catch (Exception e) {
								display.asyncExec(new Runnable() {
									
									@Override
									public void run() {
										Utils.popUpFailure(shell);
										Utils.regularCursor(display, shell);
									}
								});
							}
						}
					});
					thread.start();
					
				}
			}
		});

		return shell;
	}

	// returns true iff username and password are OK
	protected static boolean vaildateRegistrationTextFields(String username,
			String password, Shell shell) {
		if (!checkUsername(username)) {
			Utils.popUpBox("Illeagel username", "username should be  6-10 letters/digits long and start with a letter.", shell);
			return false;
		}
		if (!checkPassword(password)) {
			Utils.popUpBox("Illeagel password", "Password should be a 6 to 20 alpha/numeric string", shell);
			return false;
		}
		return true;
	}

	private static boolean checkPassword(String password) {
		return password.matches("^\\w{6,20}$");
	}

	protected static boolean checkUsername(String text) {
		return text.matches("^[a-zA-Z]\\w{5,9}$");
	}
	
	
	
}